import { createSlice, nanoid, PayloadAction } from '@reduxjs/toolkit'
// import { produce } from 'immer'
import { ComponentPropsType } from '../../components/QuestionComponents'
import { getNextSelectedId } from './utils'
import { cloneDeep } from 'lodash'
import { insertNewComponent } from './utils'
import { arrayMove } from '@dnd-kit/sortable'
// import { produce } from 'immer'

export type ComponentInfoType = {
  fe_id: string // TODO 以后解释
  type: string
  title: string
  props: ComponentPropsType
  isHidden?: boolean
  isLocked?: boolean
}

export type ComponentStateType = {
  componentList: Array<ComponentInfoType>
  selectedId: string
  copiedComponent: ComponentInfoType | null
}

const INIT_STATE: ComponentStateType = {
  componentList: [],
  selectedId: '',
  copiedComponent: null,
}

export const componentsSlice = createSlice({
  name: 'components',
  initialState: INIT_STATE,
  reducers: {
    // 重置所有罪
    resetComponents(state: ComponentStateType, action: PayloadAction<ComponentStateType>) {
      return action.payload
    },

    // 修改 selectedId
    /* changeSelectedId: produce((draft: ComponentStateType, action: PayloadAction<string>) => {
      console.log(draft)

      draft.selectedId = action.payload
    }), */
    changeSelectedId(state: ComponentStateType, action: PayloadAction<string>) {
      return {
        ...state,
        selectedId: action.payload,
      }
    },

    // 添加新组件
    addComponent(state: ComponentStateType, action: PayloadAction<ComponentInfoType>) {
      // const { selectedId, componentList } = state
      const newComponent = action.payload
      const newComponentList = insertNewComponent(state, newComponent)
      // const newComponentList = componentList.slice()
      // const selectedComponentIndex = componentList.//findIndex(c => c.fe_id === selectedId)

      //if (selectedComponentIndex >= 0) {
      //  newComponentList.splice(selectedComponentIndex + 1, 0, newComponent)
      //} else {
      //  newComponentList.push(newComponent)
      //}

      return {
        ...state,
        selectedId: newComponent.fe_id,
        componentList: newComponentList,
      }
    },

    /*  addComponent: produce((draft: ComponentStateType, action: PayloadAction<ComponentInfoType>) => {
      // const { selectedId, componentList } = draft
      console.log(draft)
      const newComponent = action.payload
      const newComponentList = insertNewComponent(draft, newComponent)
      draft.selectedId = newComponent.fe_id
      draft.componentList = newComponentList
    }), */

    // 修改组件属性
    changeComponentProps(state: ComponentStateType, action: PayloadAction<ComponentInfoType>) {
      const { selectedId, componentList } = state
      const newComponentList = componentList.map(c => {
        if (c.fe_id === action.payload.fe_id) {
          return {
            ...c,
            props: action.payload.props,
          }
        }
        return c
      })

      return {
        ...state,
        selectedId,
        componentList: newComponentList,
      }
    },

    // 删除选中的组件
    removeSelectedComponent(state: ComponentStateType) {
      const { selectedId, componentList } = state
      const newComponentList = componentList.slice()
      const selectedComponentIndex = newComponentList.findIndex(c => c.fe_id === selectedId)

      // 重新计算 selectedId
      const newSelectedId = getNextSelectedId(selectedId, componentList)

      newComponentList.splice(selectedComponentIndex, 1)

      return {
        ...state,
        selectedId: newSelectedId,
        componentList: newComponentList,
      }
    },

    // 隐藏/显示 组件
    changComponentHidden(
      { selectedId, componentList, copiedComponent }: ComponentStateType,
      action: PayloadAction<{ fe_id: string; isHidden: boolean }>
    ) {
      const { fe_id, isHidden } = action.payload
      const newComponentList = componentList.map(c => {
        if (c.fe_id === selectedId) {
          return {
            ...c,
            isHidden,
          }
        }
        return c
      })

      // 重新计算 selectedId
      let newSelectedId = ''
      if (isHidden) {
        // 要隐藏
        newSelectedId = getNextSelectedId(selectedId, componentList)
      } else {
        // 要显示
        newSelectedId = fe_id
      }

      return {
        copiedComponent,
        selectedId: newSelectedId,
        componentList: newComponentList,
      }
    },

    // 锁定/解锁 组件
    toggleComponentLocked(state: ComponentStateType, action: PayloadAction<{ fe_id: string }>) {
      const { componentList } = state
      const { fe_id } = action.payload
      const newComponentList = componentList.map(c => {
        if (c.fe_id === fe_id) {
          return {
            ...c,
            isLocked: !c.isLocked,
          }
        }
        return c
      })
      return { ...state, componentList: newComponentList }
    },

    // 拷贝当前选中的组件
    copySelectedComponent(state: ComponentStateType) {
      const { selectedId, componentList } = state
      const selectedComponent = componentList.find(c => c.fe_id === selectedId)

      return {
        ...state,
        copiedComponent: selectedComponent ? cloneDeep(selectedComponent) : null,
      }
    },

    // 粘贴组件
    pasteCopiedComponent(state: ComponentStateType) {
      const { copiedComponent } = state

      const newComponent = cloneDeep(copiedComponent)

      if (newComponent) {
        //修改 fe_id
        newComponent.fe_id = nanoid(5)
      }
      const newComponentList = insertNewComponent(state, newComponent)

      return {
        ...state,
        copiedComponent: newComponent,
        componentList: newComponentList,
      }
    },

    // 选中上一个
    selectPrevComponent(state: ComponentStateType) {
      const { selectedId, componentList } = state
      const selectedIndex = componentList.findIndex(c => c.fe_id === selectedId)
      let newSelectedId = componentList[0].fe_id

      // 未选中
      if (selectedIndex < 0) {
        return {
          ...state,
          // selectedId: newSelectedId,
        }
      }

      // 已经选中第一个无法再向上选中
      if (selectedIndex <= 0) {
        return {
          ...state,
          selectedId: newSelectedId,
        }
      }
      newSelectedId = componentList[selectedIndex - 1].fe_id

      return {
        ...state,
        selectedId: newSelectedId,
      }
    },

    // 选中下一个
    selectNextComponent(state: ComponentStateType) {
      const { selectedId, componentList } = state
      const selectedIndex = componentList.findIndex(c => c.fe_id === selectedId)
      let newSelectedId = componentList[componentList.length - 1].fe_id

      // 未选中
      if (selectedIndex < 0) {
        return {
          ...state,
          // selectedId: newSelectedId,
        }
      }

      // 已经选中最后一个, 无法再向下选中
      if (selectedIndex + 1 === componentList.length) {
        return {
          ...state,
          selectedId: newSelectedId,
        }
      }
      newSelectedId = componentList[selectedIndex + 1].fe_id

      return {
        ...state,
        selectedId: newSelectedId,
      }
    },

    // 修改组件标题
    changeComponentTitle(
      state: ComponentStateType,
      action: PayloadAction<{ fe_id: string; title: string }>
    ) {
      const { componentList } = state
      const newComponentList = componentList.map(c => {
        if (c.fe_id === action.payload.fe_id) {
          return {
            ...c,
            title: action.payload.title,
          }
        }
        return c
      })

      return {
        ...state,
        componentList: newComponentList,
      }
    },

    // 移动组件位置
    /* moveComponent: produce(
      (draft: ComponentStateType, action: PayloadAction<{ oldIdx: number; newIdx: number }>) => {
        console.log(draft)

        const { componentList: currentComponentList } = draft
        const { oldIdx, newIdx } = action.payload

        draft.componentList = arrayMove(currentComponentList, oldIdx, newIdx)
      }
    ), */
    moveComponent(
      state: ComponentStateType,
      action: PayloadAction<{ oldIdx: number; newIdx: number }>
    ) {
      const currentComponentList = state.componentList
      const { oldIdx, newIdx } = action.payload
      arrayMove(currentComponentList, oldIdx, newIdx)

      return {
        ...state,
        componentList: arrayMove(currentComponentList, oldIdx, newIdx),
      }
    },
  },
})

export const {
  resetComponents,
  changeSelectedId,
  addComponent,
  changeComponentProps,
  removeSelectedComponent,
  changComponentHidden,
  toggleComponentLocked,
  copySelectedComponent,
  pasteCopiedComponent,
  selectPrevComponent,
  selectNextComponent,
  changeComponentTitle,
  moveComponent,
} = componentsSlice.actions

export default componentsSlice.reducer
